import java.nio.charset.StandardCharsets;

public class Main {

    public static String sha1(String input) {
        if (input == null) {
            return null;
        }

        // 预处理消息
        byte[] message = input.getBytes(StandardCharsets.UTF_8);
        long messageLength = message.length * 8L; // 原始消息长度(bit)

        // 添加填充位
        int paddingLength = (56 - (message.length + 1) % 64 + 64) % 64;
        byte[] paddedMessage = new byte[message.length + 1 + paddingLength + 8];
        System.arraycopy(message, 0, paddedMessage, 0, message.length);
        paddedMessage[message.length] = (byte) 0x80; // 添加1 bit

        // 添加原始长度(64位)
        for (int i = 0; i < 8; i++) {
            paddedMessage[paddedMessage.length - 8 + i] = (byte) ((messageLength >>> (56 - i * 8)) & 0xFF);
        }

        // 初始化哈希值
        int h0 = 0x67452301;
        int h1 = 0xEFCDAB89;
        int h2 = 0x98BADCFE;
        int h3 = 0x10325476;
        int h4 = 0xC3D2E1F0;

        // 处理每个512位块
        for (int i = 0; i < paddedMessage.length; i += 64) {
            int[] w = new int[80];

            // 将16个32位字存入w[0..15]
            for (int j = 0; j < 16; j++) {
                w[j] = ((paddedMessage[i + j * 4] & 0xFF) << 24) |
                        ((paddedMessage[i + j * 4 + 1] & 0xFF) << 16) |
                        ((paddedMessage[i + j * 4 + 2] & 0xFF) << 8) |
                        (paddedMessage[i + j * 4 + 3] & 0xFF);
            }

            // 扩展16个字到80个字
            for (int j = 16; j < 80; j++) {
                w[j] = leftRotate(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
            }

            // 初始化哈希值
            int a = h0;
            int b = h1;
            int c = h2;
            int d = h3;
            int e = h4;

            // 主循环
            for (int j = 0; j < 80; j++) {
                int f, k;

                if (j < 20) {
                    f = (b & c) | ((~b) & d);
                    k = 0x5A827999;
                } else if (j < 40) {
                    f = b ^ c ^ d;
                    k = 0x6ED9EBA1;
                } else if (j < 60) {
                    f = (b & c) | (b & d) | (c & d);
                    k = 0x8F1BBCDC;
                } else {
                    f = b ^ c ^ d;
                    k = 0xCA62C1D6;
                }

                int temp = leftRotate(a, 5) + f + e + k + w[j];
                e = d;
                d = c;
                c = leftRotate(b, 30);
                b = a;
                a = temp;
            }

            // 添加到结果中
            h0 += a;
            h1 += b;
            h2 += c;
            h3 += d;
            h4 += e;
        }

        // 生成最终哈希值
        byte[] hash = new byte[20];
        for (int i = 0; i < 4; i++) {
            hash[i] = (byte) ((h0 >>> (24 - i * 8)) & 0xFF);
            hash[i + 4] = (byte) ((h1 >>> (24 - i * 8)) & 0xFF);
            hash[i + 8] = (byte) ((h2 >>> (24 - i * 8)) & 0xFF);
            hash[i + 12] = (byte) ((h3 >>> (24 - i * 8)) & 0xFF);
            hash[i + 16] = (byte) ((h4 >>> (24 - i * 8)) & 0xFF);
        }

        // 转换为十六进制字符串
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xFF & b);
            if (hex.length() == 1) {
                hexString.append('0');
            }
            hexString.append(hex);
        }

        return hexString.toString();
    }

    private static int leftRotate(int value, int shift) {
        return (value << shift) | (value >>> (32 - shift));
    }

    public static void main(String[] args) {
        String input = "iscbupt";
        String hash = sha1(input);
        System.out.println("Custom SHA-1 hash of \"" + input + "\":");
        System.out.println(hash);
    }
}